package POC;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Experment1 {

    //词法分析结果
    private static ArrayList<WordBean> wordBeanArrayList = new ArrayList<>();

    public static void main(String[] args) {

//        //从控制台输入字符串
//        Scanner scanner = new Scanner(System.in);
//
//        //读入字符串
//        String inputString = scanner.nextLine();

        StringBuilder inputString = new StringBuilder();

        //从文件读入程序
        File file = new File("D:\\daima\\Java\\homework2020\\src\\POC\\test.sql");
        if (file.exists()) {
            try {
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String temp;
                while ((temp = reader.readLine()) != null){
                    inputString.append(temp).append(" ");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            System.out.println("文件不存在！");
        }

        //括号处理
        addKH(inputString.toString());

        //转换为字符串数组
        char[] charArray = inputString.toString().replace("(", " ").replace(")", " ").toCharArray();

        for (int i = 0;i<charArray.length;i++){
            //空格跳过
            if (charArray[i] == ' ') continue;

            //字符串缓冲区
            StringBuilder charTemp = new StringBuilder();

            //是否识别到了关键字
            boolean isEnd = false;
            //非空格直到下一次空格进行识别
            while (i < charArray.length && charArray[i] != ' ') {
                charTemp.append(charArray[i]);

                //识别小数
                if (charArray[i] == '.' || charArray[i] == '_') {
                    i++;
                    continue;
                }

                //当前字符串是否为关键字
                String keyWord = isKeyWord(charTemp.toString());
                if (keyWord != null) {
                    wordBeanArrayList.add(new WordBean(WordTable.wordTable.get(keyWord), keyWord));
                    isEnd = true;
                    break;
                }

                //当前字符是否为关键字
                String nowKeyWord = isKeyWord(String.valueOf(charArray[i]));
                if (nowKeyWord != null) {
                    wordBeanArrayList.add(new WordBean(WordTable.wordTable.get(nowKeyWord), nowKeyWord));

                    //将charTemp缓冲区中的字符移除掉当前字符
                    charTemp.delete(charTemp.length() - 1, charTemp.length());
                    break;
                }

                i++;
            }

            //如果识别到了关键字/运算符 结束本次遍历
            if (isEnd) continue;

            //是否是十进制数
            boolean isD;

            //是否是八进制数
            boolean isO;

            //是否是十六进制数
            boolean isH;

            //是否为标识符
            boolean isVar;

            isD = isD(charTemp.toString(), 10);
            isO = isO(charTemp.toString());
            isH = isH(charTemp.toString());
            isVar = isVar(charTemp.toString());

            //数字或标识符直接返回
            if(isD) wordBeanArrayList.add(new WordBean(WordTable.wordTable.get("d"), charTemp.toString()));
            else if (isO) wordBeanArrayList.add(new WordBean(WordTable.wordTable.get("o"), charTemp.toString()));
            else if (isH) wordBeanArrayList.add(new WordBean(WordTable.wordTable.get("h"), charTemp.toString()));
            else if (isVar) wordBeanArrayList.add(new WordBean(WordTable.wordTable.get("var"), charTemp.toString()));
        }

        for (WordBean bean : wordBeanArrayList){
            System.out.println(bean);
        }

    }

    /**
     * 解析是否为标识符
     * 规则：第一个为字母，其余为字符或字母
     * @param string    输入字符串
     * @return          是否为标识符
     */
    private static boolean isVar(String string) {
        char char0 = string.charAt(0);
        if ((char0 >= 'a' && char0 <= 'z') || (char0 >= 'A' && char0 <= 'Z')){
            for (char c : string.toCharArray()){
                if (!Character.isLetterOrDigit(c)) return false;
            }
            return true;
        }
        return false;
    }

    /**
     * 解析字符串是否为关键字
     * @param string    数组字符
     * @return          如果是关键字/运算符 返回名字 否则返回null
     */
    private static String isKeyWord(String string) {
        switch (string){
            case "+":return "+";
            case "-":return "-";
            case "*":return "*";
            case "/":return "/";
            case ">":return ">";
            case "<":return "<";
            case "=":return "=";
            case "(":return "(";
            case ")":return ")";
            case ";":return ";";
            case "if":return "if";
            case "then":return "then";
            case "else":return "else";
            case "while":return "while";
            case "do":return "do";
            default:return null;
        }
    }

    //是否为十进制数
    private static boolean isD(String string, int radix){
        if (string.length() < 1) return false;
        try{
            //实现识别小数功能，为了方便，可以把_转化为.处理
            String[] stringList = string.replace("_", ".").split("\\.");
            for (String s : stringList){
                Integer.parseInt(s, radix);
            }
            return true;
        }catch (Exception e){
            return false;
        }
    }

    //是否是八进制数
    private static boolean isO(String string){
        if (string.length() < 2) return false;
        if ("0".equals(string.substring(0, 1))) return isD(string.substring(1), 8);
        return false;
    }

    //是否是十六进制数
    private static boolean isH(String string){
        if (string.length() < 3) return false;
        if ("0x".equals(string.substring(0, 2))) return isD(string.substring(2), 16);
        return false;
    }

    //字符串括号处理
    private static void addKH(String string){
        if (string.contains("(")) {
            wordBeanArrayList.add(new WordBean(WordTable.wordTable.get("("), "("));
        }
        if (string.contains(")")) {
            wordBeanArrayList.add(new WordBean(WordTable.wordTable.get(")"), ")"));
        }
    }
}

/**
 * 单词实体类
 * 包括单词种类和单词属性
 */
class WordBean{
    private int type;

    private String attr;

    WordBean(int type, String attr){
        this.type = type;
        this.attr = attr;
    }

    @Override
    public String toString() {
        return "WordBean{" +
                "type=" + type +
                ", attr='" + attr + '\'' +
                '}';
    }
}

class WordTable{
    //单词符号编码
    static HashMap<String, Integer> wordTable = new HashMap<>();

    static {
        wordTable.put("var", 0);
        wordTable.put("d", 1);
        wordTable.put("o", 2);
        wordTable.put("h", 3);
        wordTable.put("+", 4);
        wordTable.put("-", 5);
        wordTable.put("*", 6);
        wordTable.put("/", 7);
        wordTable.put(">", 8);
        wordTable.put("<", 9);
        wordTable.put("=", 10);
        wordTable.put("(", 11);
        wordTable.put(")", 12);
        wordTable.put(";", 13);
        wordTable.put("if", 14);
        wordTable.put("then", 15);
        wordTable.put("else", 16);
        wordTable.put("while", 17);
        wordTable.put("do", 18);
    }
}